#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "loadconfig.h"
#include <QScrollArea>
#include <QPushButton>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    graphs    = new Graphs();
    MB_Thread = new ModbusThread();     //Modbus轮询线程
    ExportThread = new QThread(this);
    exporter = new Exporter;
    exporter->moveToThread(ExportThread);
    connect(&config, &LoadConfig::SendMB_Cnf, MB_Thread, &ModbusThread::on_Modbus_Config, Qt::QueuedConnection);
    config.LoadCsv("./profile.csv");
    MB_Ctr = new Modbus_ctr(this);      //Modbus控制对象

    btnConnect = new QPushButton("连接");
    btnSave = new QPushButton("定时导出");
    btnGraph = new QPushButton("曲线图");
    btnConnect->setStyleSheet("font-size: 14px;");
    btnSave->setStyleSheet("font-size: 14px;");
    btnGraph->setStyleSheet("font-size: 14px;");
    SingalsToSlots();
    CreateBaseWidget();
    UiConstr();
    TaskListToExporter();
    TakeListToGraphs();

    this->setWindowTitle("PMK电控上位机 v.202507");
    this->resize(1388,888);
}

RegParam::RegParam()
{
    lineEdit = new QLineEdit(this);
    comboBox = new QComboBox(this);
    lineEdit->setProperty("testInstance", QVariant::fromValue(this));
}

MainWindow::~MainWindow()
{
    exporter->stop();
    ExportThread->quit();
    ExportThread->wait();
    delete ui;
}

void MainWindow::UiConstr()
{
    //     1. 创建主布局
    QGridLayout *mainLayout = new QGridLayout(ui->centralwidget);

    // 2. 添加固定区域（不滚动）
    QHBoxLayout *fixedLayout_1 = new QHBoxLayout();
    QHBoxLayout *fixedLayout_2 = new QHBoxLayout();
    QLabel *labName = new QLabel(config.ProfileName);
    SerialComBox = new QComboBox();

    SerialComBox->setStyleSheet(
                "QComboBox {"
                "    border: 1px solid #D9D9D9;"
                "    border-radius: 4px;"
                "    padding: 4px 8px;"
                "   min-width: 150px;"
                "    background: white;"
                "}"
                "QComboBox::down-arrow {"
                " width: 12px; /* 箭头宽度 */"
                "height: 12px; /* 箭头高度 */"
                " image: url(:/icons/down_arrow.svg);"
                "}"
                );
    mainLayout->addLayout(fixedLayout_1,0,0,Qt::AlignLeft);
    mainLayout->addLayout(fixedLayout_2,0,0,Qt::AlignRight);

    SerialInfo = new QLabel("设备未连接");
    SerialInfo->setStyleSheet("color: red;font-weight: bold;");
    labName->setStyleSheet("font-weight: bold;font-size: 20px;");
    fixedLayout_1->addWidget(SerialComBox);
    fixedLayout_1->addWidget(btnConnect);
    fixedLayout_1->addWidget(btnSave);
    fixedLayout_1->addWidget(btnGraph);
    fixedLayout_1->addWidget(SerialInfo);
    fixedLayout_2->addWidget(labName);

    QTabWidget *TabWidget = new QTabWidget(this);
    TabWidget->setTabPosition(QTabWidget::South);
    mainLayout->addWidget(TabWidget);
    int num = 0;
    for(auto it = config.TabSetUpParamsMap.begin(); it != config.TabSetUpParamsMap.end(); it++)
    {
        TabWidget->addTab(CreateTabPage(num++),it.value());

    }
}

QWidget* MainWindow::CreateTabPage(int num)
{
    // 主部件
    QWidget *page = new QWidget();

    // 滚动区域
    QScrollArea *scrollArea = new QScrollArea(page);
    scrollArea->setWidgetResizable(true);

    // 内容部件 - 使用QGridLayout
    QWidget *contentWidget = new QWidget();
    QGridLayout *gridLayout = new QGridLayout(contentWidget);
////////////////

    QVector<RegParam*> tmpList;
    for(int i = 0; i < RegParamList.size(); i++)
    {
       if(RegParamList[i]->tabNum == num)
       {
           tmpList.append(RegParamList[i]);
       }
    }
    int groupNum = config.GpMap.value(num).size();         //通过当前页的首个基类获取该页有几个分组框
    int row = 0, col = 0;
    for (int i = 0; i < groupNum; i ++)
    {
       QGroupBox *groupBox = new QGroupBox( config.GpMap.value(num).at(i), contentWidget);      //分组名
       QGridLayout *groupGrid = new QGridLayout(groupBox);

        for (int l= 0, xRow = 0, xCol = 0; l < tmpList.size(); l++)
        {
            if(tmpList[l]->gpNum == i)
            {
                QWidget *tmp = nullptr;
                if(tmpList[l]->WidgetType == QLINEEDIT)
                    tmp = tmpList[l]->lineEdit;
                else if(tmpList[l]->WidgetType == QCOMBOX)
                    tmp = tmpList[l]->comboBox;
                else if(tmpList[l]->WidgetType == QCHECKBOX)
                {
                    for(QCheckBox* ck : tmpList[l]->CheckBoxList)
                    {

                        groupGrid->addWidget(ck, xRow, xCol);

                        xCol++;
                        if(xCol >= 5)
                        {
                            xRow++;
                            xCol =0 ;
                        }

                    }
                    goto end;
                }
                else if(tmpList[l]->WidgetType == NOTHING)  continue;

                else continue;

               groupGrid->addWidget(tmpList[l]->name, xRow, xCol);
               groupGrid->addWidget(tmp, xRow, xCol + 1);
               groupGrid->addWidget(tmpList[l]->units, xRow, xCol + 2);
               xCol+=3;
               if(xCol >= 5)
               {
                   xRow++;
                   xCol =0 ;
               }
               end: ;
            }

           gridLayout->addWidget(groupBox, row, col);
        }
       col++;
       if(col >= 2)
       {
           row++;
           col =0 ;
       }
    }

    ///////////////////////////////
    scrollArea->setWidget(contentWidget);
    QVBoxLayout *pageLayout = new QVBoxLayout(page);
    pageLayout->addWidget(scrollArea);

    return page;
}

RegParam *MainWindow::CreateWidget(const QStringList &type)
{
    RegParam *def = new RegParam();

    //默认
    def->lineEdit->setReadOnly(true);
    def->lineEdit->installEventFilter(this);
    def->ReadOnly = false;
    def->WidgetType = QLINEEDIT;
    def->step = type.at(STEPS);

    //类型
    if(type.at(TYPE) == "v-i")
    {
        def->WidgetType = QCOMBOX;
        def->ComBoxMap = parseDataToMap(type.at(REMARK));
        def->comboBox->addItems(def->ComBoxMap.values());
    }
    else if(type.at(TYPE) == "H")
        def->IsHex = true;
    else if(type.at(TYPE) == "B")
        def->WidgetType = QCHECKBOX;
    else if(type.at(TYPE) == "R")
        def->WidgetType = NOTHING;

    //读写权限
    if(type.at(CONTROL) == nullptr)
        def->ReadOnly = true;
    //倍数
    if(type.at(STEPS) != nullptr)
    {
        def->IsMultiplier = true;
        def->step = type.at(STEPS).mid(2,type.at(STEPS).size());
        def->MultipNum = def->step.toFloat();
//        qDebug() << def->MultipNum <<  def->step;
    }
    //允许加入曲线图
    if(type.at(DISPLAY) != nullptr)
        def->AllowAddToGrap = true;
    //允许导出
    if(type.at(ICON) != nullptr)
        def->AllowExport = true;
    return def;
}

bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
    QLineEdit *line = qobject_cast<QLineEdit *>(obj);
    RegParam *base = RegParam::getTestInstance(line);

    if(event->type() == QEvent::MouseButtonDblClick && !base->ReadOnly)
    {
        if(btnConnect->text() == "连接")      //没有设置连接状态，暂时靠字符串识别
        {  QMessageBox::information(this,"提示","当前设备未连接~"); goto end;}

        bool ok = false;
        uint16_t sendVal = 0;
        if((base->IsMultiplier))
        {
            float val = QInputDialog::getDouble(this, "写入", "请输入要修改的值：",
                                                 line->text().toDouble(),INT16_MIN * base->MultipNum,INT16_MAX * base->MultipNum,base->step.size() - 2,
                                                 &ok,Qt::WindowTitleHint|Qt::WindowCloseButtonHint);

            sendVal =  qRound(val / (base->MultipNum / 10)) * base->MultipNum;
//             qDebug() <<"sendVal" <<sendVal << base->MultipNum;
            if(ok)
                line->setText(QString::number(val,'g',6));
        }
        else if((base->IsHex))
        {
            QString val = QInputDialog::getText(this, "写入", "请输入要修改的值(Hex)：",QLineEdit::Normal,line->text(),
                                                &ok,Qt::WindowTitleHint|Qt::WindowCloseButtonHint);

            sendVal = val.toInt(nullptr,16);
            if(ok)
            {
                if(!isHexString(val)){  QMessageBox::warning(this,"参数错误","输入的是非16进制数！"); goto end;}
                line->setText(val.toUpper());
            }
        }
        else
        {
            int val = QInputDialog::getInt(this, "写入", "请输入要修改的值：",
                                           line->text().toInt(nullptr,10),INT16_MIN,INT16_MAX,1,
                                           &ok,Qt::WindowTitleHint|Qt::WindowCloseButtonHint);
            sendVal = val;
            if(ok)
                line->setText(QString::number(val,10));
        }
        if(ok)
        {
            emit(WriteModbus(base->modbusAddr, sendVal));
            qDebug() << "addr:0x"+QString::number(base->modbusAddr,16)+ " value:" << sendVal;
        }
    }
end:
    return QWidget::eventFilter(obj,event);
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    Q_UNUSED(event);
    graphs->close();
    graphs->deleteLater();
}

void MainWindow::CreateBaseWidget()
{
    for (int i = 0; i < config.ParamList.size(); i++)
    {
        RegParam *base = CreateWidget(config.ParamList.at(i));
        base->name = new QLabel(config.ParamList.at(i).at(NAME) + ":");
        base->units = new QLabel(config.ParamList.at(i).at(UNIT));

        QString a = config.ParamList.at(i).at(INDEX).mid(1, config.ParamList.at(i).at(INDEX).length() - 2);
        QStringList numbers = a.split(",");

        base->tabNum = numbers[0].toInt();
        base->gpNum = numbers[1].toInt();

        if(config.ParamList.at(i).at(OFS) == nullptr)
        {
            int cnt = 0;
            int j = i;
            while(config.ParamList.at(j).at(OFS) == nullptr)
            {
                j--;
                cnt++;
            }
            base->modbusAddr = config.ParamList.at(j).at(OFS).toInt(nullptr,16) + cnt;
        }
        else
            base->modbusAddr = config.ParamList.at(i).at(OFS).toInt(nullptr,16);

        if(base->WidgetType == QLINEEDIT)
        {
            base->tmp = base->lineEdit;
            if(base->ReadOnly)
            {
                base->lineEdit->setStyleSheet(R"(
                                              QLineEdit {
                                              font-size: 14px;
                                              background-color: #f0f0f0;
                                              color: #000000;
                                              border: 1px solid #cccccc;
                                              selection-background-color: #d0d0d0;
                                              selection-color: #333333;
                                              }
                                          )");
            }
        }
        else if(base->WidgetType == QCOMBOX)
        {
            base->tmp = base->comboBox;
            if(base->ReadOnly)
            {
                base->comboBox->setEnabled(false);
                base->comboBox->setStyleSheet(R"(
                                              QComboBox {
                                                    font-size: 14px;
                                                  border: none;            /* 无边框 */
                                                  background: transparent; /* 透明背景 */
                                                  padding: 0px;            /* 无内边距 */
                                                  margin: 0px;             /* 无外边距 */
                                                  selection-background-color: transparent; /* 选中项背景透明 */
                                                  color: #000000;          /* 文字颜色 */
                                              }
                                          )");
            }else
            {
                base->comboBox->setStyleSheet(R"(
                                              QComboBox::down-arrow {
                                                  width: 12px; /* 箭头宽度 */
                                                  height: 12px; /* 箭头高度 */
                                                  image: url(:/icons/down_arrow.svg);
                                              }
                                          )");
            }
            QMetaObject::Connection c = connect(base->comboBox,
                                                QOverload<const QString &>::of(&QComboBox::currentIndexChanged),
                                                this,[=](const QString &text)
            {
                qDebug() << "Text changed to:" << text;
                auto it = base-> ComBoxMap.begin();
                for(; it != base->ComBoxMap.end(); it++)
                {
                    if(it.value() == text)  break;
                }
                qDebug() << "Key:" << it.key();
                emit(WriteModbus(base->modbusAddr,it.key()));
            });
            base->ConnectionList.append(c);
        }
        else if(base->WidgetType == QCHECKBOX)
        {
            QMap<int, QString> parsed = parseBitDescriptions(config.ParamList.at(i).at(REMARK));
            auto it = parsed.constBegin();
            for (int i = 0; i < parsed.size(); i++)
            {
                QCheckBox *tmp  = new QCheckBox();
                tmp->setLayoutDirection(Qt::RightToLeft);
                if(base->name->text().contains("故障"))
                {
                    tmp->setStyleSheet(R"(
                                       QCheckBox::indicator:unchecked:hover {
                                           background: #F5E0E0;
                                       }
                                       QCheckBox::indicator:checked {
                                           background: #FF1818;
                                           border: 2px solid #780B0B;
                                       }
                                       QCheckBox::indicator:checked:hover {
                                           background: #CF1313;
                                           border: 2px solid #780B0B;
                                       })");
                }
                QMetaObject::Connection c  = connect(tmp, &QCheckBox::clicked, this, [=](bool check){

                    if(base->ReadOnly) {tmp->toggle();return;}
                    if      (check) base->val |= (1 << (it.key()));
                    else    base->val &= ~(1 << (it.key()));
                    emit(WriteModbus(base->modbusAddr, base->val));
                    qDebug() << it.key() << base->val;
                });
                base->ConnectionList.append(c);

                tmp->setText(it.value());
                it++;
                base->CheckBoxList.append(tmp);
            }
            base->CheckBoxMapList.append(parsed);

        }
        RegParamList.append(base);  // 存入列表
    }
}

void MainWindow::TaskListToExporter()
{
    QVector<GraphsData*> list;
    for(RegParam* tmp : RegParamList)
    {
        if(tmp->AllowExport && tmp->WidgetType != NOTHING)
        {
            GraphsData *gd = new GraphsData;
            gd->Name = tmp->name->text().mid(0,tmp->name->text().size() - 1);   //去掉冒号
            gd->value = &(tmp->val);
            gd->MultipNum = &tmp->MultipNum;
            list.append(gd);
        }
    }
    exporter->GiveMeList(list);
}

void MainWindow::TakeListToGraphs()
{
    QVector<GraphsData*> list;
    for(RegParam* tmp : RegParamList)
    {
        if(tmp->AllowAddToGrap && tmp->WidgetType != NOTHING)
        {
            GraphsData *gd = new GraphsData;
            gd->Name = tmp->name->text().mid(0,tmp->name->text().size() - 1);   //去掉冒号
            gd->value = &(tmp->val);
            gd->MultipNum = &tmp->MultipNum;
            list.append(gd);
        }
    }
    graphs->GiveMeList(list);
}

void MainWindow::SingalsToSlots()
{
    connect(btnGraph,&QPushButton::clicked,this,[=]{     graphs->show();});
    connect(btnConnect,&QPushButton::clicked,this,[=]{
        emit(SendSerialConf(&config,SerialComBox->currentText().mid(0,6)));});
    connect(btnSave,&QPushButton::clicked,this,&MainWindow::on_btnSaveClicked);
    connect(MB_Ctr,&Modbus_ctr::ModbusState,this,[=](ModbusState_t state){
        switch (state)
        {
        case Connected:
            MB_Thread->start();
            btnConnect->setText("断开");
            SerialInfo->setText("");
            SerialComBox->setDisabled(true);
            break;
        case DisConnect:
            MB_Thread->threadStop();
            btnConnect->setText("连接");
            SerialInfo->setText("设备未连接");
            SerialComBox->setDisabled(false);
            break;
        case ErrConnect:
            QMessageBox::warning(this,"提示","设备操作失败,请检查串口是否被占用");
            break;
        case ErrRead:
            SerialInfo->setText("数据读取异常");
            break;
        case _MB_OK:
            SerialInfo->setText(" ");
            break;
        }
    });
    connect(MB_Thread, &ModbusThread::readRequest, MB_Ctr, &Modbus_ctr::on_readModbus);
    connect(MB_Ctr,&Modbus_ctr::serialUpdate, this,&MainWindow::on_SerialUpdate);
    connect(MB_Ctr, &Modbus_ctr::ModbusDataConver, this, &MainWindow::on_ModbusDataToUI);
    connect(this, &MainWindow::SendSerialConf,MB_Ctr ,&Modbus_ctr::on_SerialConf);
    connect(this, &MainWindow::WriteModbus,MB_Ctr ,&Modbus_ctr::on_WriteModbus);
    connect(exporter, &Exporter::taskDone, this, &MainWindow::on_ExportTaskDone);
//    connect(ExportThread, &QThread::finished, exporter, &QObject::deleteLater);
    connect(exporter, &Exporter::TaskFail, this, [=] {
        QMessageBox::critical(this, "导出失败", "无法打开文件,请不要在导出时操作文件！");
        on_btnSaveClicked();
    });
}

void MainWindow::on_SerialUpdate(QStringList items)
{
    SerialComBox->clear();
    SerialComBox->addItems(items);
}

void MainWindow::on_ModbusDataToUI(QVector<uint16_t> dat)
{

    for (int i = 0; i < dat.size(); i++)
    {
        RegParam *base = RegParamList.at(i);
        base->val = dat.at(i);
        switch (base->WidgetType)
        {
        case QLINEEDIT:
            if(base->IsMultiplier)
            {
//                qDebug() << base->MultipNum;
                base->lineEdit->setText(QString::number((qint16)dat.at(i) * base->MultipNum,'f',base->step.size() - 2));
            }
            else if(base->IsHex)
                base->lineEdit->setText(QString::number((qint16)dat.at(i),16).toUpper());
            else
                base->lineEdit->setText(QString::number((qint16)dat.at(i)));
            break;
        case QCHECKBOX:

            for(int i = 0; i < base->CheckBoxMapList.size(); i++)
            {
                int MapIndex = 0;
                for(auto it = base->CheckBoxMapList.at(i).begin(); it != base->CheckBoxMapList.at(i).end(); it++)
                {
                    if(base->val >> it.key() & 0x01)
                        base->CheckBoxList.at(MapIndex)->setChecked(true);
                    else
                        base->CheckBoxList.at(MapIndex)->setChecked(false);
                    MapIndex++;
                }
            }
            break;
        case QCOMBOX:
        {
            disconnect(base->ConnectionList.at(0));       // 断开下标改变信号连接
            base->ConnectionList.clear();
            QList<int> keys = base->ComBoxMap.keys();
            if(!base->pause)                    //防止写入后读回来的是上一次的值，暂停更新
            {
                int index = keys.indexOf(dat.at(i));
                base->comboBox->setCurrentIndex(index);
            }
            base->pause = false;                //正常更新
            QMetaObject::Connection c  = connect(base->comboBox,
                                                 QOverload<const QString &>::of(&QComboBox::currentIndexChanged),
                                                 this,[=](const QString &text)
            {
                base->pause = true;
                //                qDebug() << "Text changed to:" << text;
                auto it = base-> ComBoxMap.begin();
                for(; it != base->ComBoxMap.end(); it++)
                {
                    if(it.value() == text)  break;
                }
                //                qDebug() << "Key:" << it.key();
                emit(WriteModbus(base->modbusAddr,it.key()));
            });
            base->ConnectionList.append(c);
        }
            break;
        case NOTHING:
            break;
        default:
            qDebug() << "Unkown state!";
            break;
        }
    }
}

void MainWindow::on_ExportTaskDone(const QString &result)
{
    qDebug() << result;
}

void MainWindow::on_btnSaveClicked()
{
    if(ExportThread->isRunning())
    {
        QMetaObject::invokeMethod(exporter, "stop", Qt::QueuedConnection);
        ExportThread->quit();
        ExportThread->wait();
        btnSave->setText("定时导出");
        btnSave->setStyleSheet(
                    "QPushButton {"
                    "background-color: #ffffff;"
                    "font: 14px \"Segoe UI\", \"Microsoft YaHei\", sans-serif;"
                    "color:#000000"
                    "}"
                    );
    }
    else
    {
        bool ok;
        //获取时间间隔
        int intval = QInputDialog::getInt(
            this,                          // 父窗口
            tr("定时"),                           // 标题
            tr("请输入需要定时导出的时间间隔(秒):"),   // 提示文本
            5,                            // 默认值
            1,                             // 最小值
            MAXSHORT,                      // 最大值
            1,                             // 步长
            &ok                            // 返回是否点击OK
        );
        if(!ok) return;
        intval *= 1000;

        //获取导出路径
        CsvExporter ex;
        QStringList list;
        list.append("时间");
        for(const RegParam* tmp : RegParamList)
        {
            if(tmp->WidgetType == NOTHING || !tmp->AllowExport)  continue;
            list.append(tmp->name->text().mid(0,tmp->name->text().size() - 1).append(tmp->units->text()));
        }
        ex.setHeader(list);
        QString filePath = QFileDialog::getSaveFileName(
            this,
            "导出CSV文件",
            QDir::homePath(),
            "CSV文件 (*.csv);;所有文件 (*)"
        );
        if (!filePath.isEmpty()) {
            if (ex.exportToFile(filePath)) {
                btnSave->setText("停止导出");
                btnSave->setStyleSheet(
                            "QPushButton {"
                            "background-color: #4A90E2;"
                            "font: 14px \"Segoe UI\", \"Microsoft YaHei\", sans-serif;"
                            "color:#ffffff"
                            "}"
                            );
                QMessageBox::information(this, "导出开始", "文件已开始导出");
            }else{
                QMessageBox::warning(this, "导出失败", "文件导出失败");return;}
        }else{
            return;
        }
        QMetaObject::invokeMethod(exporter, "path", Qt::QueuedConnection,
                                 Q_ARG(QString, filePath),Q_ARG(int, intval));
        ExportThread->start();
        QMetaObject::invokeMethod(exporter, "start", Qt::QueuedConnection);
    }
}

//*  tools  *//

QMap<int, QString> MainWindow::parseDataToMap(const QString &dataStr)
{
    QMap<int, QString> resultMap;
    // 1. 按逗号分割键值对
    QStringList pairs = dataStr.split(',', Qt::SkipEmptyParts);
    for (const QString &pair : pairs)
    {
        // 2. 按冒号分割键和值
        QStringList keyValue = pair.split(':', Qt::SkipEmptyParts);

        if (keyValue.size() != 2)
        {
            qWarning() << "Invalid pair format:" << pair;
             QMessageBox::warning(this,"错误","协议中键值对编写有误");
            continue; // 跳过格式错误的键值对
        }
        // 3. 尝试将 key 转为 int
        bool ok = false;
        int key = keyValue[0].toInt(&ok);
        if (!ok)
        {
            qWarning() << "Invalid key (not an integer):" << keyValue[0];
            QMessageBox::warning(this,"错误","协议中键值对编写有误");
            continue; // 跳过无效的 key
        }
        // 4. 存入 QMap
        resultMap.insert(key, keyValue[1]);
    }

    return resultMap;
}

bool MainWindow::isHexString(const QString &qString, bool allowPrefix) {
    if (qString.isEmpty()) {
        return false;
    }
    // 检查是否有 "0x" 或 "0X" 前缀
    if (allowPrefix && (qString.startsWith("0x", Qt::CaseInsensitive))) {
        if (qString.length() <= 2) { // 只有 "0x" 或 "0X" 没有内容
            return false;
        }
        // 检查剩余部分是否全是十六进制字符
        return QRegularExpression("^[0-9a-fA-F]+$").match(qString.mid(2)).hasMatch();
    }
    // 如果没有前缀，直接检查整个字符串
    else {
        return QRegularExpression("^[0-9a-fA-F]+$").match(qString).hasMatch();
    }
}

QMap<int, QString> MainWindow::parseBitDescriptions(const QString &bitDescriptions)
{
    QMap<int, QString> result;

    QStringList entries = bitDescriptions.split(",", Qt::SkipEmptyParts);

    for (const QString& entry : entries) {
        // 分割比特位编号和描述部分
        QStringList parts = entry.split(":[");
        if (parts.size() != 2) continue;

        // 提取比特位编号
        QString bitStr = parts[0].trimmed();
        if (!bitStr.startsWith("bit-")) continue;

        bool ok;
        int bit = bitStr.mid(4).toInt(&ok); // 提取bit-后面的数字
        if (!ok || bit < 0 || bit > 15) continue;

        // 处理描述部分
        QString desc = parts[1].trimmed();
        if (desc.endsWith("]")) desc.chop(1);

        result[bit] = desc;
    }

    return result;
}

